/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package grex.Conformal;

import grex.Data.Prediction;
import grex.Data.PredictionContainer;
import grex.Environment;
import grex.WekaModels.GrexM5PBag;
import grex.WekaModels.WekaPredictiveModel;
import java.util.ArrayList;

/**
 *
 * @author RIK
 */
public class ConformalLinSAE implements IConformalMetric {
        private double beta = 0.5;
        @Override
        public double calcAlpha(Prediction prediction, double realValue) {
            PredictionContainer pc = new PredictionContainer(1);
            Prediction p = new Prediction(prediction);
            pc.put(p.getInstance(), p);
            model.execute(pc);
            double predAE = Math.max(p.getPrediction(),0.001);
            double u=predAE+beta;
            double AE = Math.abs(prediction.getPrediction() - realValue);
            AE=AE*(u);
            return AE;
        }

        @Override
        public ArrayList<Double> calcPredictionSet(Prediction prediction, double pAlpha) {
            ArrayList<Double> intervall = new ArrayList<>(2);
            PredictionContainer pc = new PredictionContainer(1);
            Prediction p = new Prediction(prediction);
            pc.put(p.getInstance(), p);
            model.execute(pc);
            double predAE = Math.max(p.getPrediction(),0.001);
            intervall.add(prediction.getPrediction() - pAlpha / (predAE+beta));
            intervall.add(prediction.getPrediction() + pAlpha / (predAE+beta));
            //System.out.println(intervall.get(LOWER)+ " U:" + intervall.get(UPPER));
            return intervall;
        }
        
        WekaPredictiveModel model;
        @Override
        public void initICPModel(Environment env, PredictionContainer pcTrain) {
            model = new GrexM5PBag(env);
            PredictionContainer pcAE = new PredictionContainer(pcTrain.size());
            for (Prediction p : pcTrain.values()) {
                Prediction newP = new Prediction(p);                
                double ae = Math.abs(p.getPrediction() - p.getTargetValue());
                    ae=Math.max(ae,0.001);
                newP.setTargetValue(ae);
                pcAE.put(p.getInstance(), newP);
            }
            model.train(pcAE);
            model.execute(pcAE);
            System.out.println("\nAEPrediction");
            for (Prediction p : pcAE.values()) {
                System.out.println("pred:" + p.getPrediction() + " Real:" + p.getTargetValue());
            }
        }
    }
